package org.java.order.rabbitcallback;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

/**
 * @author WHQ
 * @version 1.0
 * @date 2022-3-26 0026 下午 2:57
 * 自定义的回调函数，实现redisTemplate提供的回调函数的接口
 * 只要消息发送到交换机，就会触发回调
 */
@Component
@Slf4j
public class MyExchangeCallback implements RabbitTemplate.ConfirmCallback,RabbitTemplate.ReturnCallback {

    @Autowired
    private RabbitTemplate rabbitTemplate;
    //注入,将当前的类注入到RabbitTemplate.ConfirmCallback中
    @PostConstruct//在构造函数执行以后执行
    public void init(){
        //注入
        rabbitTemplate.setConfirmCallback(this);
        rabbitTemplate.setReturnCallback(this);
    }
    /**
     * 交换机确认回调的分发
     * 1.发消息，交换机接收到了以后回调
     *  1.1 correlationData 保存回调消息的id以及相关信息
     *  1.2 b 交换机收到消息为 ack=true
     *  1.3 s 为null
     * 2.发消息，交换机没有接收到了以后回调
     *  2.1 correlationData 保存回调消息的id以及相关信息
     *  2.2 b ack=false
     *  2.3 s 为错误的原因
     * @param correlationData
     * @param b
     * @param s
     */
    @Override
    public void confirm(CorrelationData correlationData, boolean b, String s) {
        String id=correlationData!=null?correlationData.getId():"";
        if (b) {
            log.info("交换机已经接收到了消息:id为{}", id);
        } else {
            //交换机接收失败
            log.info("交换机还未收到接收到了消息:id为{},原因为：{}", id,s);
        }
    }

    /**
     * 可以在当消息传递过程中不可达目的地时将消息返回给生产者
     * @param message
     * @param replyCode
     * @param replyText
     * @param exchange
     * @param routingKey
     */
    @Override
    public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
        log.error("消息{}，被交换机{}，退回了，退回原因{}，routingKey{}",
                new String(message.getBody()),exchange,
                replyText,routingKey);
    }
}
